// Copyright 2021 ETH Zurich and University of Bologna.
// Solderpad Hardware License, Version 0.51, see LICENSE for details.
// SPDX-License-Identifier: SHL-0.51
//
// Author: Matheus Cavalcante <matheusd@iis.ee.ethz.ch>
//         Basile Bougenot <bbougenot@student.ethz.ch>
//         Matteo Perotti <mperotti@iis.ee.ethz.ch>

#include "float_macros.h"
#include "vector_macros.h"

// Simple random test with similar values
void TEST_CASE1(void) {
  VSET(16, e16, m1);
  //               10.5312,  79.6250,  12.2891,  89.5000,  62.5938,  53.5625,
  //               -37.3438, -48.3750,  49.3438,  1.1475, -79.6250,  52.0000,
  //               -61.0312,  5.1641,  48.7500, -25.6250
  VLOAD_16(v2, 0x4944, 0x54fa, 0x4a25, 0x5598, 0x53d3, 0x52b2, 0xd0ab, 0xd20c,
           0x522b, 0x3c97, 0xd4fa, 0x5280, 0xd3a1, 0x452a, 0x5218, 0xce68);
  //               68.1875,
  //               -7.0742,  20.2656,  72.3125,  88.5625,  36.0000,  96.6250,  70.4375,
  //               -87.6875,  87.6875,  8.7891, -18.8906, -40.1562,  88.8750,
  //               -55.5312,  2.1875
  VLOAD_16(v3, 0x5443, 0xc713, 0x4d11, 0x5485, 0x5589, 0x5080, 0x560a, 0x5467,
           0xd57b, 0x557b, 0x4865, 0xccb9, 0xd105, 0x558e, 0xd2f1, 0x4060);
  asm volatile("vfwadd.vv v4, v2, v3");
  //               78.71875000,  72.55078125,  32.55468750,  161.81250000,
  //               151.15625000,  89.56250000,  59.28125000,  22.06250000,
  //               -38.34375000,  88.83496094, -70.83593750,  33.10937500,
  //               -101.18750000,  94.03906250, -6.78125000, -23.43750000
  VCMP_U32(1, v4, 0x429d7000, 0x42911a00, 0x42023800, 0x4321d000, 0x43172800,
           0x42b32000, 0x426d2000, 0x41b08000, 0xc2196000, 0x42b1ab80,
           0xc28dac00, 0x42047000, 0xc2ca6000, 0x42bc1400, 0xc0d90000,
           0xc1bb8000);

  VSET(16, e32, m1);
  //              -35386.17187500, -52670.69531250,  69391.31250000,
  //              3219.84130859,  74596.35156250, -45488.69921875,
  //              6598.72949219,  20221.24609375,  75105.62500000,
  //              67354.82031250,  32844.19140625, -73470.18750000,
  //              -28377.67382812,  61998.10937500,  24691.54296875,
  //              -29873.45507812
  VLOAD_32(v2, 0xc70a3a2c, 0xc74dbeb2, 0x478787a8, 0x45493d76, 0x4791b22d,
           0xc731b0b3, 0x45ce35d6, 0x469dfa7e, 0x4792b0d0, 0x47838d69,
           0x47004c31, 0xc78f7f18, 0xc6ddb359, 0x47722e1c, 0x46c0e716,
           0xc6e962e9);
  //              -90937.21875000, -72297.07031250,  18867.19531250,
  //              -516.01525879, -13301.11425781,  85173.41406250,
  //              -32079.35546875, -23770.60937500,  39295.43359375,
  //              38042.19140625, -61343.24218750,  76844.01562500,
  //              26642.50390625,  91893.05468750,  88349.72656250,
  //              29134.96093750
  VLOAD_32(v3, 0xc7b19c9c, 0xc78d3489, 0x46936664, 0xc40100fa, 0xc64fd475,
           0x47a65ab5, 0xc6fa9eb6, 0xc6b9b538, 0x47197f6f, 0x47149a31,
           0xc76f9f3e, 0x47961602, 0x46d02502, 0x47b37a87, 0x47ac8edd,
           0x46e39dec);
  asm volatile("vfwadd.vv v4, v2, v3");
  //              -126323.3906250000000000, -124967.7656250000000000,
  //              88258.5078125000000000,  2703.8260498046875000,
  //              61295.2373046875000000,  39684.7148437500000000,
  //              -25480.6259765625000000, -3549.3632812500000000,
  //              114401.0585937500000000,  105397.0117187500000000,
  //              -28499.0507812500000000,  3373.8281250000000000,
  //              -1735.1699218750000000,  153891.1640625000000000,
  //              113041.2695312500000000, -738.4941406250000000
  VCMP_U64(2, v4, 0xc0fed73640000000, 0xc0fe827c40000000, 0x40f58c2820000000,
           0x40a51fa6f0000000, 0x40edede798000000, 0x40e36096e0000000,
           0xc0d8e22810000000, 0xc0abbaba00000000, 0x40fbee10f0000000,
           0x40f9bb5030000000, 0xc0dbd4c340000000, 0x40aa5ba800000000,
           0xc09b1cae00000000, 0x4102c91950000000, 0x40fb991450000000,
           0xc08713f400000000);
};

// Simple random test with similar values (masked)
// The numbers are the same of TEST_CASE1
void TEST_CASE2(void) {
  VSET(16, e16, m1);
  //               10.5312,  79.6250,  12.2891,  89.5000,  62.5938,  53.5625,
  //               -37.3438, -48.3750,  49.3438,  1.1475, -79.6250,  52.0000,
  //               -61.0312,  5.1641,  48.7500, -25.6250
  VLOAD_16(v2, 0x4944, 0x54fa, 0x4a25, 0x5598, 0x53d3, 0x52b2, 0xd0ab, 0xd20c,
           0x522b, 0x3c97, 0xd4fa, 0x5280, 0xd3a1, 0x452a, 0x5218, 0xce68);
  //               68.1875,
  //               -7.0742,  20.2656,  72.3125,  88.5625,  36.0000,  96.6250,  70.4375,
  //               -87.6875,  87.6875,  8.7891, -18.8906, -40.1562,  88.8750,
  //               -55.5312,  2.1875
  VLOAD_16(v3, 0x5443, 0xc713, 0x4d11, 0x5485, 0x5589, 0x5080, 0x560a, 0x5467,
           0xd57b, 0x557b, 0x4865, 0xccb9, 0xd105, 0x558e, 0xd2f1, 0x4060);
  VLOAD_8(v0, 0xAA, 0xAA);
  VCLEAR(v4);
  asm volatile("vfwadd.vv v4, v2, v3, v0.t");
  //               0.00000000,  72.55078125,  0.00000000,  161.81250000,
  //               0.00000000,  89.56250000,  0.00000000,  22.06250000,
  //               0.00000000,  88.83496094,  0.00000000,  33.10937500,
  //               0.00000000,  94.03906250,  0.00000000, -23.43750000
  VCMP_U32(3, v4, 0x0, 0x42911a00, 0x0, 0x4321d000, 0x0, 0x42b32000, 0x0,
           0x41b08000, 0x0, 0x42b1ab80, 0x0, 0x42047000, 0x0, 0x42bc1400, 0x0,
           0xc1bb8000);

  VSET(16, e32, m1);
  //              -35386.17187500, -52670.69531250,  69391.31250000,
  //              3219.84130859,  74596.35156250, -45488.69921875,
  //              6598.72949219,  20221.24609375,  75105.62500000,
  //              67354.82031250,  32844.19140625, -73470.18750000,
  //              -28377.67382812,  61998.10937500,  24691.54296875,
  //              -29873.45507812
  VLOAD_32(v2, 0xc70a3a2c, 0xc74dbeb2, 0x478787a8, 0x45493d76, 0x4791b22d,
           0xc731b0b3, 0x45ce35d6, 0x469dfa7e, 0x4792b0d0, 0x47838d69,
           0x47004c31, 0xc78f7f18, 0xc6ddb359, 0x47722e1c, 0x46c0e716,
           0xc6e962e9);
  //              -90937.21875000, -72297.07031250,  18867.19531250,
  //              -516.01525879, -13301.11425781,  85173.41406250,
  //              -32079.35546875, -23770.60937500,  39295.43359375,
  //              38042.19140625, -61343.24218750,  76844.01562500,
  //              26642.50390625,  91893.05468750,  88349.72656250,
  //              29134.96093750
  VLOAD_32(v3, 0xc7b19c9c, 0xc78d3489, 0x46936664, 0xc40100fa, 0xc64fd475,
           0x47a65ab5, 0xc6fa9eb6, 0xc6b9b538, 0x47197f6f, 0x47149a31,
           0xc76f9f3e, 0x47961602, 0x46d02502, 0x47b37a87, 0x47ac8edd,
           0x46e39dec);
  VLOAD_8(v0, 0xAA, 0xAA);
  VCLEAR(v4);
  asm volatile("vfwadd.vv v4, v2, v3, v0.t");
  //               0.0000000000000000, -124967.7656250000000000,
  //               0.0000000000000000,  2703.8260498046875000,
  //               0.0000000000000000,  39684.7148437500000000,
  //               0.0000000000000000, -3549.3632812500000000,
  //               0.0000000000000000,  105397.0117187500000000,
  //               0.0000000000000000,  3373.8281250000000000,
  //               0.0000000000000000,  153891.1640625000000000,
  //               0.0000000000000000, -738.4941406250000000
  VCMP_U64(4, v4, 0x0, 0xc0fe827c40000000, 0x0, 0x40a51fa6f0000000, 0x0,
           0x40e36096e0000000, 0x0, 0xc0abbaba00000000, 0x0, 0x40f9bb5030000000,
           0x0, 0x40aa5ba800000000, 0x0, 0x4102c91950000000, 0x0,
           0xc08713f400000000);
};

// Simple random test with similar values (vector-scalar)
void TEST_CASE3(void) {
  VSET(16, e16, m1);
  double dscalar_16;
  //                              12.5859
  BOX_HALF_IN_DOUBLE(dscalar_16, 0x4a4b);
  //               2.1094,  59.2188,  89.4375,  75.2500, -4.0742,  64.7500,
  //               -82.9375, -84.9375, -48.0625,
  //               -6.1016,  29.9688,  10.6172,  52.5938, -8.5000,  70.5000,
  //               -83.6875
  VLOAD_16(v2, 0x4038, 0x5367, 0x5597, 0x54b4, 0xc413, 0x540c, 0xd52f, 0xd54f,
           0xd202, 0xc61a, 0x4f7e, 0x494f, 0x5293, 0xc840, 0x5468, 0xd53b);
  asm volatile("vfwadd.vf v4, v2, %[A]" ::[A] "f"(dscalar_16));
  //               14.69531250,  71.80468750,
  //               102.02343750,  87.83593750,  8.51171875,  77.33593750,
  //               -70.35156250, -72.35156250,
  //               -35.47656250,  6.48437500,  42.55468750,  23.20312500,  65.17968750,
  //               4.08593750,  83.08593750, -71.10156250
  VCMP_U32(5, v4, 0x416b2000, 0x428f9c00, 0x42cc0c00, 0x42afac00, 0x41083000,
           0x429aac00, 0xc28cb400, 0xc290b400, 0xc20de800, 0x40cf8000,
           0x422a3800, 0x41b9a000, 0x42825c00, 0x4082c000, 0x42a62c00,
           0xc28e3400);

  VSET(16, e32, m1);
  double dscalar_32;
  //                              -497871.25000000
  BOX_FLOAT_IN_DOUBLE(dscalar_32, 0xc8f319e8);
  //              -568507.00000000,  457995.96875000,  409553.18750000,
  //              -797866.87500000,  263520.50000000,  290072.90625000,
  //              530785.75000000,  226941.43750000,  285558.65625000,
  //              -987117.31250000, -423428.21875000, -140664.31250000,
  //              -844580.25000000,  549948.50000000,  304879.87500000,
  //              -655518.43750000
  VLOAD_32(v2, 0xc90acbb0, 0x48dfa17f, 0x48c7fa26, 0xc942caae, 0x4880ac10,
           0x488da31d, 0x4901961c, 0x485d9f5c, 0x488b6ed5, 0xc970fed5,
           0xc8cec087, 0xc8095e14, 0xc94e3244, 0x490643c8, 0x4894ddfc,
           0xc92009e7);
  asm volatile("vfwadd.vf v4, v2, %[A]" ::[A] "f"(dscalar_32));
  //              -1066378.2500000000000000, -39875.2812500000000000,
  //              -88318.0625000000000000, -1295738.1250000000000000,
  //              -234350.7500000000000000, -207798.3437500000000000,
  //              32914.5000000000000000, -270929.8125000000000000,
  //              -212312.5937500000000000, -1484988.5625000000000000,
  //              -921299.4687500000000000, -638535.5625000000000000,
  //              -1342451.5000000000000000,  52077.2500000000000000,
  //              -192991.3750000000000000, -1153389.6875000000000000
  VCMP_U64(6, v4, 0xc130458a40000000, 0xc0e3786900000000, 0xc0f58fe100000000,
           0xc133c57a20000000, 0xc10c9b7600000000, 0xc1095db2c0000000,
           0x40e0125000000000, 0xc110894740000000, 0xc109eac4c0000000,
           0xc136a8bc90000000, 0xc12c1da6f0000000, 0xc1237c8f20000000,
           0xc1347bf380000000, 0x40e96da800000000, 0xc1078efb00000000,
           0xc131996db0000000);
};

// Simple random test with similar values (vector-scalar) (masked)
void TEST_CASE4(void) {
  VSET(16, e16, m1);
  double dscalar_16;
  //                              12.5859
  BOX_HALF_IN_DOUBLE(dscalar_16, 0x4a4b);
  //                2.1094,  59.2188,  89.4375,  75.2500, -4.0742,  64.7500,
  //                -82.9375, -84.9375, -48.0625,
  //                -6.1016,  29.9688,  10.6172,  52.5938, -8.5000,  70.5000,
  //                -83.6875
  VLOAD_16(v2, 0x4038, 0x5367, 0x5597, 0x54b4, 0xc413, 0x540c, 0xd52f, 0xd54f,
           0xd202, 0xc61a, 0x4f7e, 0x494f, 0x5293, 0xc840, 0x5468, 0xd53b);
  VLOAD_8(v0, 0xAA, 0xAA);
  VCLEAR(v4);
  asm volatile("vfwadd.vf v4, v2, %[A], v0.t" ::[A] "f"(dscalar_16));
  //                0.00000000,  71.80468750,  0.00000000,  87.83593750,
  //                0.00000000,  77.33593750,  0.00000000, -72.35156250,
  //                0.00000000,  6.48437500,  0.00000000,  23.20312500,
  //                0.00000000,  4.08593750,  0.00000000, -71.10156250
  VCMP_U32(7, v4, 0x0, 0x428f9c00, 0x0, 0x42afac00, 0x0, 0x429aac00, 0x0,
           0xc290b400, 0x0, 0x40cf8000, 0x0, 0x41b9a000, 0x0, 0x4082c000, 0x0,
           0xc28e3400);

  VSET(16, e32, m1);
  double dscalar_32;
  //                              -497871.25000000
  BOX_FLOAT_IN_DOUBLE(dscalar_32, 0xc8f319e8);
  //               -568507.00000000,  457995.96875000,  409553.18750000,
  //               -797866.87500000,  263520.50000000,  290072.90625000,
  //               530785.75000000,  226941.43750000,  285558.65625000,
  //               -987117.31250000, -423428.21875000, -140664.31250000,
  //               -844580.25000000,  549948.50000000,  304879.87500000,
  //               -655518.43750000
  VLOAD_32(v2, 0xc90acbb0, 0x48dfa17f, 0x48c7fa26, 0xc942caae, 0x4880ac10,
           0x488da31d, 0x4901961c, 0x485d9f5c, 0x488b6ed5, 0xc970fed5,
           0xc8cec087, 0xc8095e14, 0xc94e3244, 0x490643c8, 0x4894ddfc,
           0xc92009e7);
  VLOAD_8(v0, 0xAA, 0xAA);
  VCLEAR(v4);
  asm volatile("vfwadd.vf v4, v2, %[A], v0.t" ::[A] "f"(dscalar_32));
  //                0.0000000000000000, -39875.2812500000000000,
  //                0.0000000000000000, -1295738.1250000000000000,
  //                0.0000000000000000, -207798.3437500000000000,
  //                0.0000000000000000, -270929.8125000000000000,
  //                0.0000000000000000, -1484988.5625000000000000,
  //                0.0000000000000000, -638535.5625000000000000,
  //                0.0000000000000000,  52077.2500000000000000,
  //                0.0000000000000000, -1153389.6875000000000000
  VCMP_U64(8, v4, 0x0, 0xc0e3786900000000, 0x0, 0xc133c57a20000000, 0x0,
           0xc1095db2c0000000, 0x0, 0xc110894740000000, 0x0, 0xc136a8bc90000000,
           0x0, 0xc1237c8f20000000, 0x0, 0x40e96da800000000, 0x0,
           0xc131996db0000000);
};

// Simple random test with similar values
void TEST_CASE5(void) {
  VSET(16, e16, m1);
  //              -4.22890615,  94.35176849, -2.66183305,  81.53971863,
  //              -30.80995941, -61.45680237,  53.70308304,  26.43629074,
  //              -50.49792862,  12.57134342, -18.77090454, -0.50017655,
  //              -33.71574402,  14.64656544,  89.57390594,  94.32437897
  VLOAD_32(v2, 0xc0875333, 0x42bcb41b, 0xc02a5b79, 0x42a31456, 0xc1f67acc,
           0xc275d3c4, 0x4256cff5, 0x41d37d86, 0xc249fde1, 0x41492439,
           0xc1962ad0, 0xbf000b92, 0xc206dcec, 0x416a5855, 0x42b325d7,
           0x42bca615);
  //              -38.1875,
  //              -22.7500,  51.3438,  8.8594,  23.0938,  32.6875,  71.7500,  7.6758,
  //              -12.8047,  98.0625, -8.7734, -73.5625,
  //              -59.0312,  44.9688,  63.8438,  30.1406
  VLOAD_16(v3, 0xd0c6, 0xcdb0, 0x526b, 0x486e, 0x4dc6, 0x5016, 0x547c, 0x47ad,
           0xca67, 0x5621, 0xc863, 0xd499, 0xd361, 0x519f, 0x53fb, 0x4f89);
  asm volatile("vfwadd.wv v4, v2, v3");
  //              -42.41640472,  71.60176849,  48.68191528,  90.39909363,
  //              -7.71620941, -28.76930237,  125.45307922,  34.11207199,
  //              -63.30261612,  110.63384247, -27.54434204, -74.06267548,
  //              -92.74699402,  59.61531448,  153.41766357,  124.46500397
  VCMP_U32(9, v4, 0xc229aa66, 0x428f341b, 0x4242ba48, 0x42b4cc56, 0xc0f6eb30,
           0xc1e62788, 0x42fae7fa, 0x420872c3, 0xc27d35e1, 0x42dd4487,
           0xc1dc5ad0, 0xc2942017, 0xc2b97e76, 0x426e7615, 0x43196aec,
           0x42f8ee15);

  VSET(16, e32, m1);
  //              -55997.9824854041071376,  64501.1750668793683872,
  //              -29542.1742966430028901, -97235.1376669598394074,
  //              -76290.1568635256844573, -53719.7602741207738291,
  //              -71738.9507989753619768,  76087.4621994893532246,
  //              88201.1680542646208778, -10676.6526112916035345,
  //              -87188.1793410585087258,  19855.3190320774738211,
  //              17509.5892884960630909,  30185.4023848686192650,
  //              54203.3669640090665780, -57884.3948619379953016
  VLOAD_64(v2, 0xc0eb57bf70853aee, 0x40ef7ea59a25db30, 0xc0dcd98b27ad1b60,
           0xc0f7bd3233e24524, 0xc0f2a0228283540c, 0xc0ea3af8542a6497,
           0xc0f183af3678fc84, 0x40f29377652b4ab0, 0x40f58892b059ab28,
           0xc0c4da5388c44d38, 0xc0f54942de94bad2, 0x40d363d46b0584c8,
           0x40d11965b6e718a0, 0x40dd7a59c0ac76c8, 0x40ea776bbe2b4e38,
           0xc0ec438ca2b580c4);
  //              -73536.78125000,  57454.64062500, -32693.95507812,
  //              -56205.09375000,  12513.70898438,  20858.82226562,
  //              12284.94335938,  61625.35156250, -11893.36132812,
  //              -46430.30078125,  30247.85937500, -94111.64843750,
  //              89016.30468750, -52090.74609375,  72764.65625000,
  //              -47109.86328125
  VLOAD_32(v3, 0xc78fa064, 0x47606ea4, 0xc6ff6be9, 0xc75b8d18, 0x464386d6,
           0x46a2f5a5, 0x463ff3c6, 0x4770b95a, 0xc639d572, 0xc7355e4d,
           0x46ec4fb8, 0xc7b7cfd3, 0x47addc27, 0xc74b7abf, 0x478e1e54,
           0xc73805dd);
  asm volatile("vfwadd.wv v4, v2, v3");
  //              -129534.7637354041071376,  121955.8156918793683872,
  //              -62236.1293747680028901, -153440.2314169598394074,
  //              -63776.4478791506844573, -32860.9380084957738291,
  //              -59454.0074396003619768,  137712.8137619893532246,
  //              76307.8067261396208778, -57106.9533925416035345,
  //              -56940.3199660585087258, -74256.3294054225261789,
  //              106525.8939759960630909, -21905.3437088813807350,
  //              126968.0232140090665780, -104994.2581431879953016
  VCMP_U64(10, v4, 0xc0ff9fec38429d77, 0x40fdc63d0d12ed98, 0xc0ee638423d68db0,
           0xc102bb01d9f12292, 0xc0ef240e5506a818, 0xc0e00b9e042a6497,
           0xc0ed07c03cf1f908, 0x4100cf868295a558, 0x40f2a13ce859ab28,
           0xc0ebe25e8231134e, 0xc0ebcd8a3d2975a4, 0xc0f22105453e9ece,
           0x40fa01de4db9c628, 0xc0d56455ff538938, 0x40feff805f15a71c,
           0xc0f9a224215ac062);
};

// Simple random test with similar values (masked)
// The numbers are the same of TEST_CASE1
void TEST_CASE6(void) {
  VSET(16, e16, m1);
  //              -4.22890615,  94.35176849, -2.66183305,  81.53971863,
  //              -30.80995941, -61.45680237,  53.70308304,  26.43629074,
  //              -50.49792862,  12.57134342, -18.77090454, -0.50017655,
  //              -33.71574402,  14.64656544,  89.57390594,  94.32437897
  VLOAD_32(v2, 0xc0875333, 0x42bcb41b, 0xc02a5b79, 0x42a31456, 0xc1f67acc,
           0xc275d3c4, 0x4256cff5, 0x41d37d86, 0xc249fde1, 0x41492439,
           0xc1962ad0, 0xbf000b92, 0xc206dcec, 0x416a5855, 0x42b325d7,
           0x42bca615);
  //              -38.1875,
  //              -22.7500,  51.3438,  8.8594,  23.0938,  32.6875,  71.7500,  7.6758,
  //              -12.8047,  98.0625, -8.7734, -73.5625,
  //              -59.0312,  44.9688,  63.8438,  30.1406
  VLOAD_16(v3, 0xd0c6, 0xcdb0, 0x526b, 0x486e, 0x4dc6, 0x5016, 0x547c, 0x47ad,
           0xca67, 0x5621, 0xc863, 0xd499, 0xd361, 0x519f, 0x53fb, 0x4f89);
  VLOAD_8(v0, 0xAA, 0xAA);
  VCLEAR(v4);
  asm volatile("vfwadd.wv v4, v2, v3, v0.t");
  //               0.00000000,  71.60176849,  0.00000000,  90.39909363,
  //               0.00000000, -28.76930237,  0.00000000,  34.11207199,
  //               0.00000000,  110.63384247,  0.00000000, -74.06267548,
  //               0.00000000,  59.61531448,  0.00000000,  124.46500397
  VCMP_U32(11, v4, 0x0, 0x428f341b, 0x0, 0x42b4cc56, 0x0, 0xc1e62788, 0x0,
           0x420872c3, 0x0, 0x42dd4487, 0x0, 0xc2942017, 0x0, 0x426e7615, 0x0,
           0x42f8ee15);

  VSET(16, e32, m1);
  //              -55997.9824854041071376,  64501.1750668793683872,
  //              -29542.1742966430028901, -97235.1376669598394074,
  //              -76290.1568635256844573, -53719.7602741207738291,
  //              -71738.9507989753619768,  76087.4621994893532246,
  //              88201.1680542646208778, -10676.6526112916035345,
  //              -87188.1793410585087258,  19855.3190320774738211,
  //              17509.5892884960630909,  30185.4023848686192650,
  //              54203.3669640090665780, -57884.3948619379953016
  VLOAD_64(v2, 0xc0eb57bf70853aee, 0x40ef7ea59a25db30, 0xc0dcd98b27ad1b60,
           0xc0f7bd3233e24524, 0xc0f2a0228283540c, 0xc0ea3af8542a6497,
           0xc0f183af3678fc84, 0x40f29377652b4ab0, 0x40f58892b059ab28,
           0xc0c4da5388c44d38, 0xc0f54942de94bad2, 0x40d363d46b0584c8,
           0x40d11965b6e718a0, 0x40dd7a59c0ac76c8, 0x40ea776bbe2b4e38,
           0xc0ec438ca2b580c4);
  //              -73536.78125000,  57454.64062500, -32693.95507812,
  //              -56205.09375000,  12513.70898438,  20858.82226562,
  //              12284.94335938,  61625.35156250, -11893.36132812,
  //              -46430.30078125,  30247.85937500, -94111.64843750,
  //              89016.30468750, -52090.74609375,  72764.65625000,
  //              -47109.86328125
  VLOAD_32(v3, 0xc78fa064, 0x47606ea4, 0xc6ff6be9, 0xc75b8d18, 0x464386d6,
           0x46a2f5a5, 0x463ff3c6, 0x4770b95a, 0xc639d572, 0xc7355e4d,
           0x46ec4fb8, 0xc7b7cfd3, 0x47addc27, 0xc74b7abf, 0x478e1e54,
           0xc73805dd);
  VLOAD_8(v0, 0xAA, 0xAA);
  VCLEAR(v4);
  asm volatile("vfwadd.wv v4, v2, v3, v0.t");
  //               0.0000000000000000,  121955.8156918793683872,
  //               0.0000000000000000, -153440.2314169598394074,
  //               0.0000000000000000, -32860.9380084957738291,
  //               0.0000000000000000,  137712.8137619893532246,
  //               0.0000000000000000, -57106.9533925416035345,
  //               0.0000000000000000, -74256.3294054225261789,
  //               0.0000000000000000, -21905.3437088813807350,
  //               0.0000000000000000, -104994.2581431879953016
  VCMP_U64(12, v4, 0x0, 0x40fdc63d0d12ed98, 0x0, 0xc102bb01d9f12292, 0x0,
           0xc0e00b9e042a6497, 0x0, 0x4100cf868295a558, 0x0, 0xc0ebe25e8231134e,
           0x0, 0xc0f22105453e9ece, 0x0, 0xc0d56455ff538938, 0x0,
           0xc0f9a224215ac062);
};

// Simple random test with similar values (vector-scalar)
void TEST_CASE7(void) {
  VSET(16, e16, m1);
  double dscalar_16;
  //              -16.64103889,  69.17821503,  38.24327850,
  //              -60.26666641,  97.95110321, -47.38455200,  94.12043762,
  //              -90.39623260, -17.02018356,  28.09982681,
  //              -85.91639709,  73.60102081, -98.61261749,
  //              -81.75864410,  40.07990265,  55.56723022
  VLOAD_32(v2, 0xc18520d9, 0x428a5b3f, 0x4218f91e, 0xc2711111, 0x42c3e6f7,
           0xc23d89c8, 0x42bc3daa, 0xc2b4cadf, 0xc1882956, 0x41e0cc72,
           0xc2abd532, 0x429333b9, 0xc2c539a9, 0xc2a3846d, 0x422051d2,
           0x425e44d8);
  //                              53.8750
  BOX_HALF_IN_DOUBLE(dscalar_16, 0x52bc);
  asm volatile("vfwadd.wf v4, v2, %[A]" ::[A] "f"(dscalar_16));
  //               37.23396301,  123.05321503,  92.11827850, -6.39166641,
  //               151.82611084,  6.49044800,  147.99543762,
  //               -36.52123260,  36.85481644,  81.97482300, -32.04139709,
  //               127.47602081, -44.73761749, -27.88364410,  93.95490265,
  //               109.44223022
  VCMP_U32(13, v4, 0x4214ef94, 0x42f61b3f, 0x42b83c8f, 0xc0cc8888, 0x4317d37c,
           0x40cfb1c0, 0x4313fed5, 0xc21215be, 0x42136b55, 0x42a3f31c,
           0xc2002a64, 0x42fef3b9, 0xc232f352, 0xc1df11b4, 0x42bbe8e9,
           0x42dae26c);

  VSET(16, e32, m1);
  double dscalar_32;
  //               366783.2934919928666204, -648147.5638866436202079,
  //               24949.3815817765425891, -211759.8585660880198702,
  //               337740.3714956413023174, -528559.3617047512670979,
  //               -863948.2704646114725620, -463848.5980863422155380,
  //               958859.3069495267700404, -853775.5625991101842374,
  //               -7020.6864214694360271,  839278.6509590207133442,
  //               -443325.1460256360005587,  97289.3425237806513906,
  //               220009.0786798361223191,  491284.4355713783297688
  VLOAD_64(v2, 0x411662fd2c892a3c, 0xc123c7a720b5c00a, 0x40d85d586bd5f8c0,
           0xc109d97ede57e5ac, 0x41149d317c695a78, 0xc120215eb9315d7b,
           0xc12a5d988a7a566a, 0xc11c4fa26470bf00, 0x412d43169d287d06,
           0xc12a0e1f200cfd96, 0xc0bb6cafb9514280, 0x41299cdd4d4a8032,
           0xc11b0ef49587be8c, 0x40f7c0957afa3740, 0x410adb48a122e4d8,
           0x411dfc51be066c64);
  //                               572932.37500000
  BOX_FLOAT_IN_DOUBLE(dscalar_32, 0x490be046);
  asm volatile("vfwadd.wf v4, v2, %[A]" ::[A] "f"(dscalar_32));
  //               939715.6684919928666204, -75215.1888866436202079,
  //               597881.7565817765425891,  361172.5164339119801298,
  //               910672.7464956413023174,  44373.0132952487329021,
  //               -291015.8954646114725620,  109083.7769136577844620,
  //               1531791.6819495267700404, -280843.1875991101842374,
  //               565911.6885785305639729,  1412211.0259590207133442,
  //               129607.2289743639994413,  670221.7175237806513906,
  //               792941.4536798361223191,  1064216.8105713783297688
  VCMP_U64(14, v4, 0x412cad875644951e, 0xc0f25cf305ae0050, 0x41223ef3835eafc6,
           0x41160b5210d40d2a, 0x412bcaa17e34ad3c, 0x40e5aaa06cea2850,
           0xc111c31f94f4acd4, 0x40faa1bc6e3d0400, 0x41375f8fae943e83,
           0xc111242cc019fb2c, 0x4121452f608d5d7b, 0x41358c7306a54019,
           0x40ffa473a9e105d0, 0x4124741b6f5f46e8, 0x412832dae848b936,
           0x41303d18cf819b19);
};

// Simple random test with similar values (vector-scalar) (masked)
void TEST_CASE8(void) {
  VSET(16, e16, m1);
  double dscalar_16;
  //               -16.64103889,  69.17821503,  38.24327850,
  //               -60.26666641,  97.95110321, -47.38455200,  94.12043762,
  //               -90.39623260, -17.02018356,  28.09982681,
  //               -85.91639709,  73.60102081, -98.61261749,
  //               -81.75864410,  40.07990265,  55.56723022
  VLOAD_32(v2, 0xc18520d9, 0x428a5b3f, 0x4218f91e, 0xc2711111, 0x42c3e6f7,
           0xc23d89c8, 0x42bc3daa, 0xc2b4cadf, 0xc1882956, 0x41e0cc72,
           0xc2abd532, 0x429333b9, 0xc2c539a9, 0xc2a3846d, 0x422051d2,
           0x425e44d8);
  //                              53.8750
  BOX_HALF_IN_DOUBLE(dscalar_16, 0x52bc);
  VLOAD_8(v0, 0xAA, 0xAA);
  VCLEAR(v4);
  asm volatile("vfwadd.wf v4, v2, %[A], v0.t" ::[A] "f"(dscalar_16));
  //                0.00000000,  123.05321503,  0.00000000, -6.39166641,
  //                0.00000000,  6.49044800,  0.00000000, -36.52123260,
  //                0.00000000,  81.97482300,  0.00000000,  127.47602081,
  //                0.00000000, -27.88364410,  0.00000000,  109.44223022
  VCMP_U32(15, v4, 0x0, 0x42f61b3f, 0x0, 0xc0cc8888, 0x0, 0x40cfb1c0, 0x0,
           0xc21215be, 0x0, 0x42a3f31c, 0x0, 0x42fef3b9, 0x0, 0xc1df11b4, 0x0,
           0x42dae26c);

  VSET(16, e32, m1);
  double dscalar_32;
  //                366783.2934919928666204, -648147.5638866436202079,
  //                24949.3815817765425891, -211759.8585660880198702,
  //                337740.3714956413023174, -528559.3617047512670979,
  //                -863948.2704646114725620, -463848.5980863422155380,
  //                958859.3069495267700404, -853775.5625991101842374,
  //                -7020.6864214694360271,  839278.6509590207133442,
  //                -443325.1460256360005587,  97289.3425237806513906,
  //                220009.0786798361223191,  491284.4355713783297688
  VLOAD_64(v2, 0x411662fd2c892a3c, 0xc123c7a720b5c00a, 0x40d85d586bd5f8c0,
           0xc109d97ede57e5ac, 0x41149d317c695a78, 0xc120215eb9315d7b,
           0xc12a5d988a7a566a, 0xc11c4fa26470bf00, 0x412d43169d287d06,
           0xc12a0e1f200cfd96, 0xc0bb6cafb9514280, 0x41299cdd4d4a8032,
           0xc11b0ef49587be8c, 0x40f7c0957afa3740, 0x410adb48a122e4d8,
           0x411dfc51be066c64);
  //                               572932.37500000
  BOX_FLOAT_IN_DOUBLE(dscalar_32, 0x490be046);
  VLOAD_8(v0, 0xAA, 0xAA);
  VCLEAR(v4);
  asm volatile("vfwadd.wf v4, v2, %[A], v0.t" ::[A] "f"(dscalar_32));
  //                0.0000000000000000, -75215.1888866436202079,
  //                0.0000000000000000,  361172.5164339119801298,
  //                0.0000000000000000,  44373.0132952487329021,
  //                0.0000000000000000,  109083.7769136577844620,
  //                0.0000000000000000, -280843.1875991101842374,
  //                0.0000000000000000,  1412211.0259590207133442,
  //                0.0000000000000000,  670221.7175237806513906,
  //                0.0000000000000000,  1064216.8105713783297688
  VCMP_U64(16, v4, 0x0, 0xc0f25cf305ae0050, 0x0, 0x41160b5210d40d2a, 0x0,
           0x40e5aaa06cea2850, 0x0, 0x40faa1bc6e3d0400, 0x0, 0xc111242cc019fb2c,
           0x0, 0x41358c7306a54019, 0x0, 0x4124741b6f5f46e8, 0x0,
           0x41303d18cf819b19);
};

int main(void) {
  enable_vec();
  enable_fp();

  TEST_CASE1();
  TEST_CASE2();
  TEST_CASE3();
  TEST_CASE4();

  TEST_CASE5();
  TEST_CASE6();
  TEST_CASE7();
  TEST_CASE8();

  EXIT_CHECK();
}
